import socket
#import fcntl
import time
import struct
import threading

'''
通信协议：
第一字节
自己的ID

第二字节包标记
0：登录包
1：登出包
2：数据包

登录包内容：目标机ID
登出包内容：无
数据包内容：数据
'''

class ClientInfo:
    def __init__(self, Addr, TagID):
        self.addr = Addr
        self.targetID = TagID

class MyHost:
    def __init__(self):
        self.running = True
        self.host = ''
        self.port = 8083
        self.addr = (self.host, self.port)
        self.SockUDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  #UDP协议
        self.SockUDP.bind(self.addr)
        self.CliList = {}
        #获取本机名称
        self.myname = socket.getfqdn(socket.gethostname())
        print('host name：', self.myname)
        #获取本机ip
        #print(socket.inet_ntoa(fcntl.ioctl(s.fileno(),0x8915,struct.pack('256s', ifname[:15]))[20:24]))
        self.myaddr = socket.gethostbyname(self.myname)
        print('ip:', self.myaddr, '   port:', self.port)
        self.thread = threading.Thread(target = self.run, args=()).start()  #打开收数据的线程
        input()
        self.running = False
        
    def run(self):
        print('host is running...\n(UDP)')
        while self.running:
            try:
                CliData, CliAddr = self.SockUDP.recvfrom(1024) #等待接受数据
            except:
                time.sleep(0.1)
                continue
            if not CliData:
                continue
            #print(CliData)
            #print(CliAddr)
            ClientID = CliData[0]
            PacketType = CliData[1]
            ThisClient = self.CliList.get(ClientID)
            if PacketType == 0:
                self.CliList[ClientID] = ClientInfo(CliAddr, CliData[2])
                self.SockUDP.sendto(b'ok', CliAddr)
                print('\n client connected:')
                print(ClientID, CliAddr)
            elif PacketType == 1:
                if ThisClient != None:
                    print('\n client disconnected:')
                    print(ClientID, CliAddr)
                    del self.CliList[ClientID]
            elif PacketType == 2:
                if ThisClient != None:
                    ThisClient.Addr = CliAddr
                    TagretClient = self.CliList.get(ThisClient.targetID)
                    if TagretClient != None:
                        self.SockUDP.sendto(CliData, TagretClient.addr)                

           
if __name__ == '__main__':
    host = MyHost()
    
